import tensorflow as tf
import numpy as np
from cn.redguest.pbase.model.Dense import Dense as Dense

'''
此网络包含了一个回归，并在从网络通过一个无监督类似来学习主网络
输入向量维度：1
输出向量维度：1
'''


def main():
    bat_size = 1000
    train_num = 30000
    learning_speed = 1e-2
    tf_number_type = tf.float64
    np_number_type = np.float64

    x = tf.placeholder(tf_number_type)
    y = tf.placeholder(tf_number_type)

    l1 = Dense(x, 1, 2, tf.nn.tanh, d_type=tf_number_type)
    l2 = Dense(l1.y, 2, 3, tf.nn.tanh, d_type=tf_number_type)
    l3 = Dense(l2.y, 3, 1, d_type=tf_number_type)

    loss = tf.reduce_mean(tf.square(y - l3.y))
    optimizer = tf.train.GradientDescentOptimizer(learning_speed)
    train = optimizer.minimize(loss)

    c1 = Dense(x, 1, 2, tf.nn.tanh, d_type=tf_number_type)
    c2 = Dense(c1.y, 2, 3, tf.nn.sigmoid, d_type=tf_number_type)
    c3 = Dense(c2.y, 3, 1, d_type=tf_number_type)

    c_loss = tf.reduce_mean(tf.square(y - c3.y))
    c_optimizer = tf.train.GradientDescentOptimizer(learning_speed);
    c_train = c_optimizer.minimize(c_loss)

    init = tf.initialize_all_variables()

    s = tf.Session()
    s.run(init)

    merged = tf.summary.merge_all()  # 将图形、训练过程等数据合并在一起
    writer = tf.summary.FileWriter('logs', s.graph, flush_secs=10)  # 将训练日志写入到logs文件夹下

    train_x = np.random.rand(1 * bat_size).astype(np_number_type).reshape([bat_size, 1])
    train_y = train_x * 2

    for i in range(train_num):
        _ = s.run(train, feed_dict={
            x: train_x,
            y: train_y
        })
        if i % 2000 == 0:
            print(l1.Weights.eval(s), l2.Weights.eval(s), l3.Weights.eval(s))

    print("--主方程回归评价--")
    print(s.run(l3.y, feed_dict={x: np.array([[0.3], [0.1], [0.5]], dtype=np.float64)}))

    print("用噪音在主方程进行回归，用于监督从方程")
    '''
        生成噪音样本
    '''
    train_c_x = np.random.rand(1 * 2000).astype(np_number_type).reshape([2000, 1])
    train_c_y = s.run(l3.y, feed_dict={
        x: train_c_x
    })

    for k in range(train_num):
        s.run(c_train, feed_dict={
            x: train_c_x,
            y: train_c_y
        })
        if k % 2000 == 0:
            print(c1.Weights.eval(s), c2.Weights.eval(s), c3.Weights.eval(s))

    print("--学习方程回归评价--")
    print(s.run(c3.y, feed_dict={x: np.array([[0.3], [0.1], [0.5]], dtype=np.float64)}))


if __name__ == "__main__":
    main()
